package es.indra.druida.desktop.configurator.DataLoaders.filesystem;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.jsp.JspWriter;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import es.indra.druida.desktop.configurator.DataLoaders.AbstractLoader;
import es.indra.druida.desktop.configurator.beans.AppParameter;
import es.indra.druida.desktop.configurator.beans.Configuration;
import es.indra.druida.desktop.configurator.beans.Engine;
import es.indra.druida.desktop.configurator.beans.FileType;
import es.indra.druida.desktop.configurator.beans.Parameter;
import es.indra.druida.desktop.utils.DesktopWriter;
import es.indra.druida.desktop.utils.DesktopXmlUtils;

/**
 * The Class ConfigurationLoader.
 */
public class ConfigurationLoader extends AbstractLoader{

	/** The xml file name. */
	private String xmlFileName = null;
	
	/**
	 * Instantiates a new configuration loader.
	 * 
	 * @param xmlFileName
	 *            the xml file name
	 */
	public ConfigurationLoader(String xmlFileName){
		super();
		this.xmlFileName = xmlFileName;
	}	
	
	/* (non-Javadoc)
	 * @see es.indra.druida.desktop.configurator.DataLoaders.AbstractLoader#setObjects(java.lang.Object[])
	 */
	public void setObjects(Object[] objects) throws Exception {
		// TODO Auto-generated method stub
	}
	
	/* (non-Javadoc)
	 * @see es.indra.druida.desktop.configurator.DataLoaders.AbstractLoader#getObjects()
	 */
	public Object[] getObjects() throws Exception {
		Configuration desktopConfigRet=new Configuration();
		File xmlFile=new File(xmlFileName);
		if (xmlFile.exists())	{
			Document doc = DesktopXmlUtils.getDocumentFromFile(xmlFile);
			NodeList props = doc.getDocumentElement().getChildNodes();
			for ( int i = 0 ; i < props.getLength(); i++) {
				Node node=props.item(i);
				if(node.getNodeType()==Node.ELEMENT_NODE && node.getFirstChild()!=null && node.getFirstChild().getNodeValue()!=null)	{
					Element prop = (Element) node;
					String nombre= prop.getNodeName();
					if (nombre.equals("noSessionSave")){
						desktopConfigRet.setNoSessionSave(prop.getFirstChild().getNodeValue());
					} else if (nombre.equals("soleUser"))	{
						desktopConfigRet.setSoleUser(prop.getFirstChild().getNodeValue());
					}else if (nombre.equals("engines"))	{
						NodeList engines = prop.getElementsByTagName("engine");
						ArrayList <Engine> engineRet=new ArrayList<Engine>();	
						for ( int j = 0 ; j < engines.getLength(); j++) {
							Element engine = (Element) engines.item(j);
							if (engine.hasAttribute("id")){
								Engine newEngine=new Engine(engine.getAttribute("id"));
								if (engine.hasAttribute("description"))
									newEngine.setDescription(engine.getAttribute("description"));
								if (engine.hasAttribute("url"))
									newEngine.setUrl(engine.getAttribute("url"));
								
								ArrayList <AppParameter> paramsEng=new ArrayList<AppParameter>();
								NodeList params = engine.getElementsByTagName("parameter");
								for ( int k = 0 ; k < params.getLength(); k++) {
									Element parametro=(Element)params.item(k);
									paramsEng.add(new AppParameter(parametro.getAttribute("name"), null));
								}
								newEngine.setPermittedParameters( paramsEng.toArray(new AppParameter[0]) );
								
								ArrayList <Parameter> confParams=new ArrayList<Parameter>();
								NodeList confParamsNL = engine.getElementsByTagName("configParam");
								for ( int m = 0 ; m < confParamsNL.getLength(); m++) {
									Element parametro=(Element)confParamsNL.item(m);
									confParams.add(new Parameter(parametro.getAttribute("name"), parametro.getFirstChild().getNodeValue() ));
								}
								newEngine.setConfigParameters( confParams.toArray(new Parameter[0]) );
								engineRet.add(newEngine);
							}
						}
						desktopConfigRet.setEngines( engineRet.toArray(new Engine[0]));
						
					}else if (nombre.equals("fileTypes"))	{
						NodeList fileTypes = prop.getElementsByTagName("fileType");
						ArrayList<FileType> fileTypesRet= new ArrayList<FileType>();
						for ( int j = 0 ; j < fileTypes.getLength(); j++) {
							Element fileType = (Element) fileTypes.item(j);
							fileTypesRet.add(new FileType(fileType.getAttribute("extension"),fileType.getAttribute("application")));
						}
						desktopConfigRet.setFileTypes(fileTypesRet.toArray(new FileType[0]));
					}
				}
			}
			Configuration[] ret={desktopConfigRet};
			return ret;
		}else{
			System.out.println("ERROR: ConfigurationLoader Cant find "+xmlFile);
			return null;
		}
	}
	
	/**
	 * Genera js inicializar desde xml.
	 * 
	 * @param doc
	 *            the doc
	 * @param out
	 *            the out
	 * 
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void generaJsInicializarDesdeXml(Document doc, JspWriter out) throws IOException	{
		//TO-DO: la lectura del xml es optimizable
		
		//Generamos el HTML de los MOTORES
		StringBuffer _htmlMotores = new StringBuffer();
		NodeList _elems = doc.getElementsByTagName("engine");
		for ( int i = 0 ; i < _elems.getLength(); i++) {
			Element _elem = (Element) _elems.item(i);
			if (i>0)
				_htmlMotores.append(",");
			_htmlMotores.append(DesktopWriter.generaCadenaJavascript(_elem.getAttribute("id")));
			_htmlMotores.append(":{");
			NamedNodeMap losAtribs = _elem.getAttributes();
			for (int j=0;j<losAtribs.getLength();j++)	{
				Node elAtrib = losAtribs.item(j);
				//if (!elAtrib.getNodeName().equals("parameters"))	{
					if (j>0)
						_htmlMotores.append(",");
					if (elAtrib.getNodeName().equals("description"))
						_htmlMotores.append("\"descripcion\":");
					else
						_htmlMotores.append("\""+elAtrib.getNodeName()+"\":");
					_htmlMotores.append(DesktopWriter.generaCadenaJavascript(elAtrib.getNodeValue()));					
				//}
			}
			_htmlMotores.append("}");//TO-DO: parametros
		}

		//Generamos el HTML de los TIPOS DE FICHERO
		StringBuffer _htmlTipos = new StringBuffer();
		_elems = doc.getElementsByTagName("fileType");
		for ( int i = 0 ; i < _elems.getLength(); i++) {
			Element _elem = (Element) _elems.item(i);
			if (i>0)
				_htmlTipos.append(",");
			_htmlTipos.append(DesktopWriter.generaCadenaJavascript(_elem.getAttribute("extension")));
			_htmlTipos.append(":{");
			_htmlTipos.append("aplicacion:");
			_htmlTipos.append(DesktopWriter.generaCadenaJavascript(_elem.getAttribute("application")));			
			_htmlTipos.append("}");			
		}		
		
		
		out.print("\n oMotores={");
		out.print(_htmlMotores.toString());
		out.print("};");
		
		out.print("\n oTipos={");
		out.print(_htmlTipos.toString());
		out.print("};");		
	}

	@Override
	public void addObjects(Object[] objects) throws Exception {
		// TODO Auto-generated method stub
		
	}	
}
